#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QBasicTimer>
#include <QLabel>
#include <QGridLayout>
#include <QStackedWidget>
#include "serverenum.h"
#include "vmsmanager.h"
#include "operatewindow.h"
#include "previewwidget.h"
#include "groupwidget.h"
#include "groupmanager.h"
#include "operationtaskstrace.h"
#include "titlebarwidget.h"
#include "assistantwidgets.h"
#include "logindialog.h"

#define NR_COL 3
#define NR_ROW 30
#define MAX_VIEWS (NR_COL * NR_ROW)

namespace Ui {
class MainWindow;
}

class PreviewWidget;
class GroupView;
class TabBar;
class QToolBarMenuButton;
class PreviewAreaBase;
class VmsMapView;
class VmsListView;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0, ServerEnum *servers = 0);
    ~MainWindow();
    void showServerVms();
    int currentPreviewMode();
    int getPreviewAreaWidth();

    int vmWidth;
    int vmHeight;
    int dispWidth;
    int dispHeight;
    ServerEnum *servers;
    VmsManager *vmsManager;
    GroupsManager *groupsManager;
    UserAccessControlClient *accountControl;
    //QList<PreviewWidget *> subWinList;
    //QList<VmInfo *> onShownVms;
    GroupWidget *groupWidget;
    OperationTasksTrace *tasksTrace;
    TitleBarWidget *titleBar;
    LoginDialog *loginDialog;
    BandPhoneDialog *bandPhoneDialog;

    VmsMapView *vmsMapView;
    VmsListView *vmsListView;

private:
    Ui::MainWindow *ui;
    QBasicTimer flushTimer;

signals:
    void sendCommand(const char *ipaddr, int targetPort, const QString &commandline, QObject *sender=NULL);
    void removeTask(const int);

private slots:
    void onGroupLaunchBtnClicked();
    void onGroupCloseBtnClicked();
    void onGroupInstallAppBtnClicked();
    void onGroupUninstallAppBtnClicked();
    void onMassCreateBtnClicked();
    void onMassRemoveBtnClicked();
    void onMassShakeBtnClicked();
    void onMassUseScriptBtnClicked();
    void onMassImportContactsBtnClicked();
    void onMassModifySettingsBtnClicked();
    void onShowGroupOperationClicked();
    void onShowMassOperationClicked();
    void onPreviewModeSwitched();
    void onAddVmsToGroupBtnClicked();

public slots:
    void onAddPreviewWidget(VmInfo *);
    void onRemovePreviewWidget(const char *ipaddr, const int vmPort);
    void onUpdatePreviewStatus(const char *ipaddr, const int vmPort, int newStatus);
    void onVmGroupChanged(int);
    void onTaskStatusChanged(const int taskId, const int status, QByteArray backwords);
    void onSetSelectAll(void);
    void onTipsBarCloseBtnClicked(void);
    void onShowOperationTips(const QString &text, int delay=3000);
    void hideAniomationFinished();
    void showLoginDialog(int index=LoginDialog::LOGIN_WIDGET_INDEX);
    void quitLogin();
    void onShowBandPhone(int type);
    void onUserAuthStateChanged(int state);

public slots:
    void setWindowPos(QPoint pos);
    void slotClose();
    void removeItem(VmInfo *vm);

protected:
    void timerEvent(QTimerEvent *event);
/*    void mouseMoveEvent(QMouseEvent *);
    void mousePressEvent(QMouseEvent *);
    void mouseReleaseEvent(QMouseEvent *);
*/
    void resizeEvent(QResizeEvent *event);

private:
    void setupMainUI();
    void createMassOpsBox();
    QString getNameTag(VmInfo &data);
    void setWindowVisible(bool isVisible);
    QWidget *operationTipsBar;
    QLabel *tipsBarLabel;
    QBasicTimer tipsShowTimer;
    QPropertyAnimation *tipsAnimation;
    //void updateItemWidgets(void);
    //QList<VmInfo *> getCheckedVms();
    //PreviewWidget *findItem(const char *ipaddr, int vmPort);
    //PreviewWidget *getMouseOnItem(const QPoint &pos);
    //PreviewWidget *findIndicatorItem(const int taskId);
    //PreviewWidget *lastHoverItem;
    QPushButton *btnMapPreview, *btnListPreview;
    QToolBarMenuButton *selectAllBtn, *createBtn, *removeBtn, *addVmsToGroupBtn;
    QLabel *hSpacerLabel;
    //QList<PreviewWidget *> subWinList;
    PreviewAreaBase *vmsGroupView;
    QStackedWidget *previewStackedWidget;
    QPushButton *maxBtn;
    bool isMax;
};

extern MainWindow *w;

class GroupPreviewData : public QObject
{
    Q_OBJECT
public:
    QList<VmInfo *> vms;
    //QList<VmInfo *> selectedVms;
    GroupPreviewData (QList<VmInfo*> &s_vms, QObject *parent=0);

signals:
    //void getSelectedVms(QList<VmInfo *> );
    void selectedVmChanged(QList<VmInfo *> &vms);
    //void load(QList<VmInfo*> &vms);
    //void removeAll();
    //void removeVm(const char *ipaddr, const int vmPort);
    //void addVm(VmInfo *vm);
    //void updateVm(VmInfo *vm);
};

class PreviewAreaBase : public QWidget
{
    Q_OBJECT
public:
    //PreviewAreaBase (GroupPreviewData *data, QWidget *parent=0);
    PreviewAreaBase (QWidget *parent=0);
    virtual void load(QList<VmInfo *> &vms);
    virtual void removeAll();
    virtual void removeItem(const char *ipaddr, const int vmPort);
    virtual void addItem(VmInfo *vm);
    virtual void updateItem(VmInfo *vm);
    virtual void setSelected(const char *ipaddr, const int vmPort, bool isSelected);
    virtual bool selected(const char *ipaddr, const int vmPort);
    virtual QList<VmInfo *> getSelectedVms(bool selectRunningVms=false);
    virtual void selectAll() {}
    //GroupPreviewData *m_data;
signals:
    void selectedVmChanged(QList<VmInfo *> &vms);
};

class VmsMapView : public PreviewAreaBase
{
    Q_OBJECT
public:
    //VmsMapView (GroupPreviewData *data, QWidget *parent=0);
    VmsMapView(QWidget *parent=0);
    ~VmsMapView();
    QList<VmInfo *> getSelectedVms(bool selectRunningVms=false);
    void setSelected(const char *ipaddr, const int vmPort, bool isSelected);
    bool selected(const char *ipaddr, const int vmPort);
    void load(QList<VmInfo *> &vms);
    void removeAll();
    void removeItem(const char *ipaddr, const int vmPort);
    void addItem(VmInfo *vm);
    void updateItem(VmInfo *vm);
    void selectAll();
    void flushPreviewArea();
    void addIndicatorPreviewWidget(const int taskId);
    void cancelIndicatorPreviewWidget(const int taskId, int status, QByteArray backwords);
    void updateIndicatorPreviewWidget(const int taskId, QByteArray backwords);
    void updateItemWidgets(void);
    void updateItemStatus(const int taskId, int status, QByteArray backwords="");

public slots:
    void onUpdatePreviewStatus(const char *ipaddr, const int vmPort, int newStatus);
    void onSelectedVmChanged(QList<VmInfo *> &);

protected slots:
    void mouseMoveEvent(QMouseEvent *);

private:
    //void updateItemWidgets(void);
    PreviewWidget *getMouseOnItem(const QPoint &pos);
    PreviewWidget *findIndicatorItem(const int taskId);
    PreviewWidget *findItem(const char *ipaddr, int vmPort);
    QList<PreviewWidget *> subWinList;
    QGridLayout *gridViewLayout;
    PreviewWidget *lastHoverItem;
    QMainWindow *m_parent;
    QString currentOps;
    //char currentOps[512];
    //QBasicTimer flushTimer;
 };

class VmsListView : public PreviewAreaBase
{
    Q_OBJECT
public:
    //VmsListView(GroupPreviewData *data, QWidget *parent=0);
    VmsListView(QWidget *parent=0);
    ~VmsListView();
    QList<VmInfo *> getSelectedVms(bool selectRunningVms=false);
    void setSelected(const char *ipaddr, const int vmPort, bool isSelected);
    bool selected(const char *ipaddr, const int vmPort);
    void load(QList<VmInfo *> &vms);
    void removeAll();
    void removeItem(const char *ipaddr, const int vmPort);
    void addItem(VmInfo *vm);
    void updateItem(VmInfo *vm);
    void selectAll();

public slots:
    void onSelectedVmChanged(QList<VmInfo *> &vms);
    void onRunningStatusChanged(const char *ipaddr, const int vmPort, int status);

private:
    int findItem(const char *ipaddr, const int vmPort);
    QStringList predefines;
    QStandardItemModel *m_model;
    QTableView *m_view;
};

#endif // MAINWINDOW_H
